package com.longer.demo.biz.service.impl;

import com.longer.demo.biz.domain.OrderDO;
import com.longer.demo.biz.domain.SequenceDO;
import com.longer.demo.biz.repository.OrderDOMapper;
import com.longer.demo.biz.repository.SequenceDOMapper;
import com.longer.demo.biz.service.ItemService;
import com.longer.demo.biz.service.OrderService;
import com.longer.demo.biz.service.SequenceService;
import com.longer.demo.biz.service.UserService;
import com.longer.demo.biz.service.model.ItemModel;
import com.longer.demo.biz.service.model.OrderModel;
import com.longer.demo.biz.service.model.UserModel;
import com.longer.demo.framework.error.BusinessError;
import com.longer.demo.framework.error.BusinessException;
import org.junit.Test;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;

/**
 * @program: demo
 * @description:
 * @author: SunBiaoLong
 * @create: 2019-01-14 21:43
 **/
@Service
public class OrderServiceImpl implements OrderService {
	@Autowired(required = false)
	private OrderDOMapper orderDOMapper;

	@Autowired
	private ItemService itemService;

	@Autowired
	private SequenceService sequenceService;
	@Autowired
	private UserService userService;

	private static final String ORDER_SEQUENCE_NAME="order_info";
	@Override
	@Transactional
	public OrderModel createOrder(Integer itemId, Integer userId, Integer account) throws BusinessException {
		//校验信息
		ItemModel itemModel = itemService.getItemById(itemId);
		if (itemModel == null) {
			throw new BusinessException(BusinessError.PARAMETER_VALIDATION_ERROR, "没有此商品信息");
		}
		UserModel userModel = userService.getUserModelById(userId);
		if (userModel == null) {
			throw new BusinessException(BusinessError.PARAMETER_VALIDATION_ERROR, "用户信息错误");
		}
		if (account <= 0 || account > 99) {
			throw new BusinessException(BusinessError.PARAMETER_VALIDATION_ERROR, "请重新选择商品数量");
		}

		//减少库存
		if (!itemService.minusStock(account, itemId)) {
			throw new BusinessException(BusinessError.STOCK_INSUFFICIENT);
		}

		//创建商品model
		OrderModel orderModel = convertToOrderModel(itemModel, userModel, account);
		//生成do
		OrderDO orderDO = convertFromOrderModel(orderModel);
		//订单总是唯一的,即使回滚了主事务
		String orderNo = sequenceService.generateSequence(ORDER_SEQUENCE_NAME);
		orderDO.setId(orderNo);

		//增加销售量
		orderDOMapper.insertSelective(orderDO);

		itemService.increaseSales(orderDO.getAccount(),orderDO.getItemId());


		//保存订单

		return null;
	}

	/**
	 * 获取日期
	 */
	@Test
	public void testDate() {
		LocalDate date = LocalDate.now();
		System.out.println(date.toString().replace("-", ""));
	}

	/**
	 * 目前未考虑sequence;最大值的问题
	 * 生成OrderNo,如果创建订单的时候出现了异常,生成的订单号不应该回滚
	 *     这样保证了订单编号的唯一性
	 * @TODO 事务不能使用于没有override的方法上--核心是动态代理实现事务的切面--没看懂
	 * @return
	 */
//	@Transactional(propagation=Propagation.REQUIRES_NEW)
//	private String generateOrderNO() {
//		//订单号为16位
//		StringBuilder stringBuilder = new StringBuilder();
//		//前八位为年月日
//		String dateString = LocalDate.now().toString().replace("-", "");
//		stringBuilder.append(dateString);
//
//		//中间六位为自增序列
//		SequenceDO sequenceDO = sequenceDOMapper.getSequenceByName("order_info");
//		int sequence = sequenceDO.getCurrentValue();
////		@TODO 需要设置最大值.如果超过最大值,那么应该重新开始循环
//		sequenceDO.setCurrentValue(sequence+sequenceDO.getStep());
//		sequenceDOMapper.updateByPrimaryKey(sequenceDO);
//		String sequenceStr = String.valueOf(sequence);
//		for (int i = 0; i < 6-sequenceStr.length(); i++) {
//			stringBuilder.append(0);
//		}
//		stringBuilder.append(sequenceStr);
//
//		//最后两位为 分库分表位--制定某用户的指定订单保存的表
//		//这里不做演示
////		Integer userId = 100023;
////		int tableIndex = userId % 100;
//		//暂时写死
//		stringBuilder.append("00");
//
//		return stringBuilder.toString();
//	}

	/**
	 *
	 * @param orderModel
	 * @return
	 */

	private OrderDO convertFromOrderModel(OrderModel orderModel) {
		if (orderModel == null) {
			return null;
		}
		OrderDO orderDO = new OrderDO();
		BeanUtils.copyProperties(orderModel, orderDO);
		orderDO.setItemPrice(orderModel.getItemPrice().doubleValue());
		orderDO.setOrderPrice(orderModel.getOrderPrice().doubleValue());
		return orderDO;
	}

	private OrderModel convertToOrderModel(ItemModel itemModel, UserModel userModel, Integer account) {
		OrderModel orderModel = new OrderModel();
		orderModel.setAccount(account);
		orderModel.setItemId(itemModel.getId());
		orderModel.setItemPrice(itemModel.getPrice());
		orderModel.setUserId(userModel.getId());
		orderModel.setOrderPrice(itemModel.getPrice().multiply(BigDecimal.valueOf(account)));
		return orderModel;
	}
}
